package cn.hznc.controller.service.toolImport;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.controller.service.inventory.InventoryLocationService;
import cn.hznc.controller.service.inventory.ToolPartService;
import cn.hznc.controller.service.schedule.ToolScheduleService;
import cn.hznc.domain.entity.ToolPartEntity;
import cn.hznc.domain.request.inventory.InboundAssemblyReq;
import cn.hznc.domain.request.inventory.InboundUniqueToolReq;
import cn.hznc.domain.request.inventory.OutboundUniqueAssemblyReq;
import cn.hznc.domain.request.inventory.UniqueAssemblyToolVo;
import cn.hznc.domain.request.toolImport.BatchImportOfToolsReq;
import cn.hznc.exception.ToolLifeCycleException;
import cn.hznc.utils.CommonUtil;
import cn.hznc.mapper.ToolPartMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ScanningGunImportService {
    @Resource
    private ToolPartMapper toolPartMapper;

    @Resource
    private ToolPartService toolPartService;

    @Resource
    private InventoryLocationService inventoryLocationService;

    @Resource
    private ToolScheduleService toolScheduleService;

    public void checkToolIsExist(String uniqueId) throws Exception {
        LambdaQueryWrapper<ToolPartEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ToolPartEntity::getUniqueId, uniqueId);
        ToolPartEntity toolPartEntity = toolPartMapper.selectOne(queryWrapper);
        if (toolPartEntity == null) {
            throw new Exception("刀具不存在");
        }
    }

//    @Transactional
//    public Boolean batchImportOfTools(BatchImportOfToolsReq batchImportOfToolsReq){
//        if (CollectionUtil.isNotEmpty(batchImportOfToolsReq.getUniqueIdList())){
//            List<String> uniqueIdList = batchImportOfToolsReq.getUniqueIdList();
//            Map<String,Integer> map = new HashMap<>();
//            uniqueIdList.forEach(s -> {
//                Integer index = s.indexOf(".");
//                String toolNo = s.substring(index+1,s.indexOf(".",index+1));
//                if (map.containsKey(toolNo)){
//                    map.replace(toolNo,map.get(toolNo)+1);
//                }else {
//                    map.put(toolNo,1);
//                }
//            });
//            List<InboundAssemblyReq> inboundAssemblyReqs = new ArrayList<>();
//            uniqueIdList.forEach(s -> {
//                Integer index = s.indexOf(".");
//                String toolNo = s.substring(index+1,s.indexOf(".",index+1));
//                List<Map<String , Integer>> mapList = inventoryLocationService.findLocationIdAndNumber(Integer.valueOf(batchImportOfToolsReq.getWarehouseId()),map.get(toolNo),toolNo);
//                mapList.forEach(stringIntegerMap -> {
//                    InboundAssemblyReq inboundAssemblyReq = new InboundAssemblyReq();
//                    inboundAssemblyReq.setAssemblyUniqueId(s);
//                    inboundAssemblyReq.setNumber(stringIntegerMap.get("number"));
//                    inboundAssemblyReq.setOperator(batchImportOfToolsReq.getOperator());
//                    inboundAssemblyReq.setLocationId(stringIntegerMap.get("inventoryLocationId"));
//                    inboundAssemblyReqs.add(inboundAssemblyReq);
//                });
//            });
//            EmpInboundAssemblyToolReq empInboundAssemblyToolReq = new EmpInboundAssemblyToolReq();
//            empInboundAssemblyToolReq.setInboundAssemblyReqs(inboundAssemblyReqs);
//            toolScheduleService.empInboundAssemblyTool(empInboundAssemblyToolReq);
//        }
//        return Boolean.TRUE;
//    }

    //@Transactional
    public Boolean batchImportOfTools(BatchImportOfToolsReq batchImportOfToolsReq) {
        if (CollectionUtil.isNotEmpty(batchImportOfToolsReq.getUniqueIdList())) {
            //分割总成和零件list
            List<String> originalList = batchImportOfToolsReq.getUniqueIdList();
            //总成
            batchImportOfToolsReq.setUniqueIdList(batchImportOfToolsReq
                    .getUniqueIdList()
                    .stream()
                    .filter(uniqueId ->
                            StringUtils.isNotBlank(uniqueId) && uniqueId.startsWith("02")
                    ).collect(Collectors.toList()));
            batchImportOfAssemblyTools(batchImportOfToolsReq, batchImportOfToolsReq.getUniqueIdList()
                    .stream()
                    .map(s -> toolPartService.getByUniqueId(s))
                    .collect(Collectors.toList()));
            //零件
            batchImportOfToolsReq.setUniqueIdList(originalList
                    .stream()
                    .filter(uniqueId ->
                            StringUtils.isNotBlank(uniqueId) && uniqueId.startsWith("01")
                    ).collect(Collectors.toList()));
            batchImportOfToolParts(batchImportOfToolsReq, batchImportOfToolsReq.getUniqueIdList()
                    .stream()
                    .map(s -> toolPartService.getByUniqueId(s))
                    .collect(Collectors.toList()));
        }
        return Boolean.TRUE;
    }

    private void batchImportOfAssemblyTools(BatchImportOfToolsReq batchImportOfToolsReq, List<ToolPartEntity> inboundToolParts) {
        //判断是否需要出库
        for (ToolPartEntity inboundToolPart : inboundToolParts) {
            if (ObjectUtil.isNotNull(inboundToolPart) && ObjectUtil.isNotNull(inboundToolPart.getInventoryLocationId()) && inboundToolPart.getInventoryLocationId() > 0) {
                UniqueAssemblyToolVo uniqueAssemblyToolVo = new UniqueAssemblyToolVo();
                uniqueAssemblyToolVo.setUniqueId(inboundToolPart.getUniqueId());
                uniqueAssemblyToolVo.setId(inboundToolPart.getId());
                uniqueAssemblyToolVo.setInventoryLocationId(inboundToolPart.getInventoryLocationId());
                uniqueAssemblyToolVo.setToolNo(inboundToolPart.getToolNo());
                OutboundUniqueAssemblyReq outboundUniqueAssemblyReq = new OutboundUniqueAssemblyReq();
                outboundUniqueAssemblyReq.setOperator(batchImportOfToolsReq.getOperator());
                outboundUniqueAssemblyReq.setBatchAssemblyTool(Arrays.asList(uniqueAssemblyToolVo));
                try {
                    inventoryLocationService.outboundUniqueAssemblyTool(outboundUniqueAssemblyReq);
                } catch (ToolLifeCycleException e) {
                    log.error(e.getCode(), e.getMsg());
                }
            }
        }
        Map<String, List<ToolPartEntity>> groupByToolNo = inboundToolParts
                .stream()
                .collect(Collectors.groupingBy(ToolPartEntity::getToolNo));
        groupByToolNo.forEach((k, v) -> {
            //获取入库的库位以及对应的列表
            List<Map<String, Integer>> locationIdAndNumber = inventoryLocationService.findLocationIdAndNumber(batchImportOfToolsReq.getWarehouseId(), v.size(), k);
            List<String> uniqueIds = v.stream()
                    .map(ToolPartEntity::getUniqueId)
                    .collect(Collectors.toList());
            //调用唯一id入库接口
            if (CollectionUtil.isNotEmpty(locationIdAndNumber)) {
                for (Map<String, Integer> stringIntegerMap : locationIdAndNumber) {
                    Integer number = stringIntegerMap.get("number");
                    //每次按照数量分割 第一次分割后 接下来的循环需要去后面的uniqueId
                    List<List<String>> subList = CommonUtil.subListReload(uniqueIds, number);
                    for (String uniqueId : subList.get(0)) {
                        InboundAssemblyReq inboundAssemblyReq = new InboundAssemblyReq();
                        inboundAssemblyReq.setNumber(1);
                        inboundAssemblyReq.setLocationId(stringIntegerMap.get("inventoryLocationId"));
                        inboundAssemblyReq.setOperator(batchImportOfToolsReq.getOperator());
                        inboundAssemblyReq.setAssemblyUniqueId(uniqueId);
                        try {
                            inventoryLocationService.inboundUniqueAssemblyTool(inboundAssemblyReq);
                        } catch (ToolLifeCycleException e) {
                            log.error(e.getCode(), e.getMsg());
                        }
                    }
                    uniqueIds = uniqueIds.stream().filter(s -> !subList.get(0).contains(s)).collect(Collectors.toList());
                }
//                locationIdAndNumber.forEach(stringIntegerMap -> {
//
//                });
            }

        });
    }

    private void batchImportOfToolParts(BatchImportOfToolsReq batchImportOfToolsReq, List<ToolPartEntity> inboundToolParts) {
        //判断是否需要出库
        for (ToolPartEntity inboundToolPart : inboundToolParts) {
            if (ObjectUtil.isNotNull(inboundToolPart) && ObjectUtil.isNotNull(inboundToolPart.getInventoryLocationId()) && inboundToolPart.getInventoryLocationId() > 0) {
                //执行刀柄出库操作
                InboundUniqueToolReq inboundUniqueToolReq = new InboundUniqueToolReq();
                inboundUniqueToolReq.setInboundToolUniqueIds(Arrays.asList(inboundToolPart.getUniqueId()));
                inboundUniqueToolReq.setLocationId(inboundToolPart.getInventoryLocationId());
                inboundUniqueToolReq.setPartno(inboundToolPart.getPartno());
                inboundUniqueToolReq.setOperator(batchImportOfToolsReq.getOperator());
                try {
                    inventoryLocationService.outboundUniqueTool(inboundUniqueToolReq);
                } catch (ToolLifeCycleException e) {
                    log.error(e.getCode(), e.getMsg());
                }
            }
        }
        Map<String, List<ToolPartEntity>> groupByPartNo = inboundToolParts
                .stream()
                .collect(Collectors.groupingBy(ToolPartEntity::getPartno));
        groupByPartNo.forEach((k, v) -> {
            //获取入库的库位以及对应的列表
            List<Map<String, Integer>> locationIdAndNumber = inventoryLocationService.findLocationIdAndNumber(batchImportOfToolsReq.getWarehouseId(), v.size(), k);
            List<String> uniqueIds = v.stream()
                    .map(ToolPartEntity::getUniqueId)
                    .collect(Collectors.toList());
            //调用唯一id入库接口
            if (CollectionUtil.isNotEmpty(locationIdAndNumber)) {
                for (Map<String, Integer> stringIntegerMap : locationIdAndNumber) {
                    Integer number = stringIntegerMap.get("number");
                    List<List<String>> subList = CommonUtil.subListReload(uniqueIds, number);
                    InboundUniqueToolReq inboundUniqueToolReq = new InboundUniqueToolReq();
                    inboundUniqueToolReq.setNumber(number);
                    inboundUniqueToolReq.setPartno(k);
                    inboundUniqueToolReq.setInboundToolUniqueIds(subList.get(0));
                    inboundUniqueToolReq.setOperator(batchImportOfToolsReq.getOperator());
                    inboundUniqueToolReq.setLocationId(stringIntegerMap.get("inventoryLocationId"));
                    try {
                        inventoryLocationService.inboundUniqueTool(inboundUniqueToolReq);
                    } catch (ToolLifeCycleException e) {
                        log.error(e.getCode(), e.getMsg());
                    }
                    //入库成功后将入库的这些rfid从list中移除
                    uniqueIds = uniqueIds.stream().filter(s -> !subList.get(0).contains(s)).collect(Collectors.toList());
                }
            }

        });
    }

}
